import { Injectable, BadRequestException } from '@nestjs/common';
import { extname, join } from 'path';
import { existsSync, mkdirSync } from 'fs';
import { writeFile } from 'fs/promises';

/**
 * 文件上传服务
 */
@Injectable()
export class UploadService {
  private readonly uploadPath = 'uploads/navigation';
  private readonly allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp'];
  private readonly maxFileSize = 5 * 1024 * 1024; // 5MB

  constructor() {
    this.ensureUploadDirExists();
  }

  /**
   * 确保上传目录存在
   */
  private ensureUploadDirExists(): void {
    const fullPath = join(process.cwd(), 'public', this.uploadPath);
    if (!existsSync(fullPath)) {
      mkdirSync(fullPath, { recursive: true });
    }
  }

  /**
   * 验证文件类型
   * @param filename 文件名
   * @returns 是否为允许的文件类型
   */
  private isValidFileType(filename: string): boolean {
    const ext = extname(filename).toLowerCase();
    return this.allowedExtensions.includes(ext);
  }

  /**
   * 生成唯一文件名
   * @param originalName 原始文件名
   * @returns 新的文件名
   */
  private generateFileName(originalName: string): string {
    const ext = extname(originalName);
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    return `${timestamp}_${random}${ext}`;
  }

  /**
   * 上传文件
   * @param file 上传的文件
   * @returns 文件访问路径
   */
  async uploadFile(file: any): Promise<string> {
    // 验证文件是否存在
    if (!file) {
      throw new BadRequestException('请选择要上传的文件');
    }

    // 验证文件大小
    if (file.size > this.maxFileSize) {
      throw new BadRequestException('文件大小不能超过5MB');
    }

    // 验证文件类型
    if (!this.isValidFileType(file.originalname)) {
      throw new BadRequestException('只支持图片文件格式：jpg, jpeg, png, gif, svg, webp');
    }

    // 生成新文件名
    const fileName = this.generateFileName(file.originalname);
    const filePath = join(process.cwd(), 'public', this.uploadPath, fileName);
    const accessPath = `/${this.uploadPath}/${fileName}`;

    try {
      // 保存文件
      await writeFile(filePath, file.buffer);
      return accessPath;
    } catch (error) {
      throw new BadRequestException('文件上传失败');
    }
  }

  /**
   * 批量上传文件
   * @param files 上传的文件数组
   * @returns 文件访问路径数组
   */
  async uploadFiles(files: any[]): Promise<string[]> {
    if (!files || files.length === 0) {
      throw new BadRequestException('请选择要上传的文件');
    }

    const uploadPromises = files.map(file => this.uploadFile(file));
    return await Promise.all(uploadPromises);
  }
}